package org.apache.servicecomb.fence.auth;

import java.util.HashSet;
import java.util.Set;

import org.apache.servicecomb.fence.exception.TokenValidationException;
import org.apache.servicecomb.fence.token.JWTToken;
import org.apache.servicecomb.fence.token.JWTTokenStore;
import org.apache.servicecomb.fence.util.CommonConstants;
import org.apache.servicecomb.foundation.common.utils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import com.huaweicloud.common.context.InvocationContext;
import com.huaweicloud.common.context.InvocationContextHolder;

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@Component
public class TokenInterceptor implements HandlerInterceptor {

  @Value("${global.token.check.enabled:true}") // 默认开启校验
  private boolean tokenCheckEnabled;

  @Autowired
  private JWTTokenStore jwtTokenStore;

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

    // by pass authentication
    if (!tokenCheckEnabled) {
      return true;
    }

    String idTokenValue = request.getHeader(CommonConstants.CONTEXT_HEADER_AUTHORIZATION);

    if (idTokenValue == null) {
      throw new TokenValidationException("not authenticated");
    }

    // verify tokens
    JWTToken idToken = jwtTokenStore.createTokenByValue(idTokenValue);
    if (idToken == null) {
      throw new TokenValidationException("not authenticated");
    }

    Set<GrantedAuthority> grantedAuthorities = new HashSet<>(idToken.getClaims().getAuthorities().size());
    idToken.getClaims().getAuthorities().forEach(v -> grantedAuthorities.add(new SimpleGrantedAuthority(v)));
    createSecurityContext(grantedAuthorities);
    return true;
  }

  // 模拟 Token 验证逻辑，可以根据需求实现具体验证
  private void createSecurityContext(Set<GrantedAuthority> grantedAuthorities) {
    SecurityContext sc = new SecurityContextImpl();
    Authentication authentication = new SimpleAuthentication(true, grantedAuthorities);
    sc.setAuthentication(authentication);
    SecurityContextHolder.setContext(sc);
  }
}